///////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
#include <Texture/TextureManager.h>
#include <Texture/Texture.h>

//-----------------------------------------------------------------------------

TextureManager::TextureManager()
{
	m_textures.clear();
	m_defaultTexture = NULL;
	CreateDefaultTexture();
}

//-----------------------------------------------------------------------------

TextureManager::~TextureManager()
{
	ReleaseTextures();
}

//-----------------------------------------------------------------------------

void	TextureManager::ReleaseTextures()
{
	std::vector<Texture*>::iterator iter;
	for( iter = m_textures.begin(); iter != m_textures.end(); iter++ )
	{
		SAFE_DEL( *iter );
	}
}

//-----------------------------------------------------------------------------

void	TextureManager::CreateDefaultTexture()
{
	GLuint	defTex;
	glGenTextures(1, &defTex);
	glBindTexture(GL_TEXTURE_2D, defTex);
	
	// GL_LINEAR does not make sense for depth texture. However, next tutorial shows usage of GL_LINEAR and PCF
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	
	// Remove artefact on the edges of the shadowmap
	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );

	u8 v[3] = {250,0,0};
	glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, v);
	glBindTexture(GL_TEXTURE_2D, 0);

	m_defaultTexture = MGL_NEW	Texture( "_default_" );
	m_defaultTexture->Load( defTex );
}

//-----------------------------------------------------------------------------

void	TextureManager::AddTexture(Texture* tex)
{
	if( !tex )
		return;
	//search
	std::vector<Texture*>::iterator iter;
	for( iter = m_textures.begin(); iter != m_textures.end(); iter++ )
	{
		if( (*iter) == tex )
		{
			return;
		}
	}

	m_textures.push_back( tex );
}

//-----------------------------------------------------------------------------

void	TextureManager::AddTexture(std::string filename)
{
	Texture*	tex = MGL_NEW Texture();
	if( tex->Load( filename ) )
	{
		m_textures.push_back( tex );
	}
	else
	{
		SAFE_DEL( tex );
	}
}

//-----------------------------------------------------------------------------

Texture*	TextureManager::GetTexture(std::string filename)
{
	//search
	std::vector<Texture*>::iterator iter;
	for( iter = m_textures.begin(); iter != m_textures.end(); iter++ )
	{
		if( (*iter)->IsThisTexture(filename) )
		{
			return (*iter);
		}
	}

	//try loading
	Texture*	tex = MGL_NEW Texture();
	tex->Load( filename );
	if( tex->isLoaded() )
	{
		m_textures.push_back( tex );
		return tex;
	}

	SAFE_DEL( tex );
	return m_defaultTexture;
}

//-----------------------------------------------------------------------------

Texture*	TextureManager::GetTextureOrCreate(std::string filename)
{
	//search
	std::vector<Texture*>::iterator iter;
	for( iter = m_textures.begin(); iter != m_textures.end(); iter++ )
	{
		if( (*iter)->IsThisTexture(filename) )
		{
			return (*iter);
		}
	}

	//try loading
	Texture*	tex = MGL_NEW Texture( filename );
	tex->Load( filename );
	m_textures.push_back( tex );

	return tex;
}

//-----------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
